home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 5
/
Apprentice-Release5.iso
/
Source Code
/
C
/
Applications
/
MacGzip 1.0
/
source
/
Mac
/
EventLoop.c
next >
Wrap
Text File
|
1995-12-30
|
19KB
|
944 lines
/*
* Copyright (C) 1995 SPDsoft
*
*/
#include <stdio.h>
#include <stdarg.h>
#include <limits.h>
/*
* THINK_C 8.0 extra includes (Not in MacHeaders)
*/
#include <Aliases.h>
#include <Sound.h>
#include "MacGzip.h"
#include "GzErrors.h"
#include "ErrorStrings.h"
#include "GzPStrings.h"
#include "Prefs.h"
#include "FileTypes.h"
#include "Globals.h"
#include "Work.h"
#define CGF_MAX_TYPES 4
#define CustomGetFileDLOG 160
#define kShowAnyButton 10
#if GENERATINGCFM || USESROUTINEDESCRIPTORS
# define CreateRoutineDescriptor(info, proc) \
RoutineDescriptor g##proc##RD = BUILD_ROUTINE_DESCRIPTOR(info, proc)
# define GetRoutineAddress(proc) (&g##proc##RD)
#else
# define GetRoutineAddress(proc) proc
#endif
/************************************************************************************
*
* Movable Modal Stuff
*
* MM from C.K. Haun (Apple DTS) (MModal 7.0)
* Color Alysoft Solutions <heathcot@bnr.ca> (CModalProgress)
*/
/*
* Prototypes
*/
static void DrawMovable(WindowPtr myWindow);
static void DrawBar(short part);
static short FixMMString( void );
static void DrawMsg(void);
static void BeginOfTask( void );
static Boolean EndOfTask( int errorcode );
static int RecurseDir(long dirIDToSearch);
static int DoOpen( FSSpec *fs );
/*
* (Too many) Globals (we could group them in a struct and set it in refCon)
*/
#if GENERATINGCFM && !defined(__MWERKS__)
QDGlobals qd;
#endif
static Boolean gTask = FALSE;
Boolean UseMModalProg=false;
static Rect barRect;
static Rect greyRect;
static Rect r; /* Window's rect */
static Rect MsgRect;
static ControlHandle ButtonHndl = nil;
long int SPDEnd,
*SPDNow = nil;
Str255 SPDPstr="\p";
char* SPDpstr=(char*)SPDPstr;
static Boolean gDirtyStr;
#define kMyModalKind 1000
#define kMyModalID 150
#define kCancelButton 150
#define kIndicatorOutline 0x0001
#define kIndicatorContent 0x0002
#define BarHeight 13
#define BarMargin 20
/************************************************************************************
*
* more generic globals
*/
typedef struct
{
short numTypes;
OSType typeList[CGF_MAX_TYPES];
Boolean ShowAny;
Boolean Inited;
} TypeList;
extern TSufMap gSufMap;
static pascal short MySFGetDlgHook( short MySFitem, DialogPtr dlgPtr, void *myDataPtr );
static pascal Boolean MyCustomFileFilter(ParmBlkPtr pb, void *myDataPtr);
extern void about(void);
extern Boolean DoPrefsDialog(PrefsTypePtr thePrefs, AliasHandle * theFldrAlias);
Boolean EventLoop( void );
static Boolean DoCommand( long mResult );
static Boolean DoMouseDown(short windowPart, WindowPtr whichWindow, EventRecord *theEvent);
extern int gzip ( FSSpec *fs );
/************************************************************************************
*
* main event loop. Returns true when it has to end
*/
Boolean EventLoop( void )
{
typedef long (*MyProcPtr)( WindowPtr w );
EventRecord theEvent;
MyProcPtr drawProc;
WindowPtr twindow;
short windowPart;
static long int TheLastTime;
Boolean done = FALSE;
static long SPDLast = 0;
if (gApp.quit)
return true;
if (gApp.Working)
{
UpdateAnimatedCursor( gApp.Cursor, TickCount() );
/*
* Update bar
*/
if ((UseMModalProg) && ( SPDLast != *SPDNow ))
{
greyRect.left = greyRect.right;
greyRect.right =
((float)*SPDNow/SPDEnd)*(barRect.right-barRect.left) + barRect.left;
DrawBar(kIndicatorContent);
SPDLast = *SPDNow;
}
/*
* Update string
*/
if ((gDirtyStr) && (UseMModalProg))
DrawMsg();
}
else if ( !gTask )
{
if ( !empty_work )
{
FSSpec fs;
int rescode=0;
BeginOfTask();
do
{
if ( noErr == get_work( &gApp.KeysMode, &gApp.Op, &gApp.Prompt, &fs ))
{
rescode = DoOpen( &fs );
EndOfTask( rescode );
}
else
break;
} while (!gApp.quit && !empty_work);
done = (( gApp.StartupFiles ) || ( gPrefs.Misc.QuitWhenDone ));
}
}
while((GetNextEvent(everyEvent, &theEvent)) && !done)
{
switch( theEvent.what )
{
case keyDown:
case autoKey:
{
register char theChar;
theChar = theEvent.message & charCodeMask;
if ((theEvent.modifiers & cmdKey) != 0)
{
if ((theChar == '.' ) && gApp.Working)
{
SetCursor(&qd.arrow);
done = true;
}
else
done = DoCommand( MenuKey(theChar) );
}
break;
}
case mouseDown:
windowPart = FindWindow(theEvent.where, &twindow);
done = DoMouseDown(windowPart, twindow, &theEvent);
break;
case activateEvt:
case updateEvt:
if ( gApp.Working ) /* if working */
{
/*
* Make sure it's my window before I jump through the refCon
* Why, since DA's have they're own layer in 7.0?
* BECAUSE there are other people in the universe who will
* add things to your windowList.BalloonWriter, for example,
* so you still need to be careful
*/
if (((WindowPeek)theEvent.message)->windowKind == kMyModalKind)
{
drawProc = (MyProcPtr)GetWRefCon((WindowPtr)theEvent.message);
drawProc((WindowPtr)theEvent.message);
}
}
break;
case diskEvt:
if ((theEvent.message >> 16) != noErr)
{
Point myPoint={100,100};
err = DIBadMount(myPoint, theEvent.message);
DoError(SYS_ERR,WARN_ERR,GetErrFmt(GENERIC, BAD_DISK));
}
break;
case osEvt:
switch ((theEvent.message >> 24) & 0x0ff)
{
case suspendResumeMessage:
if ((theEvent.message & resumeFlag) == 0) // suspend
{
gApp.InForeground = FALSE;
SetCursor(&qd.arrow);
}
else
{ // resume
gApp.InForeground = TRUE;
if (gApp.Working)
UpdateAnimatedCursor( gApp.Cursor, theEvent.when );
else
SetCursor(&qd.arrow);
}
break;
case mouseMovedMessage:
break;
}
break;
case kHighLevelEvent:
AEProcessAppleEvent (&theEvent);
done = gApp.quit;
break;
default:
break;
}
}
return done;
}
static Boolean DoCommand( long mResult )
{
short theItem;
Str255 name;
Boolean done=FALSE;
/* custom get file stuff */
StandardFileReply mySFR;
#if GENERATINGCFM || USESROUTINEDESCRIPTORS
CreateRoutineDescriptor(uppFileFilterYDProcInfo, MyCustomFileFilter);
CreateRoutineDescriptor(uppDlgHookYDProcInfo, MySFGetDlgHook);
#endif
static TypeList MyTypeList = {
4,
{ 'Gzip','ZIVU','ZIVM','pZIP' },
FALSE,
FALSE
};
Point sfgfpos = { -1, -1 };
theItem = LoWord(mResult);
switch( HiWord(mResult) )
{
case kAppleMenu:
if( theItem > 2 )
{
GrafPtr savePort;
GetItem(GetMHandle(kAppleMenu), theItem, name);
GetPort(&savePort);
OpenDeskAcc(name);
SetPort(savePort);
}
else
{
about();
}
break;
case kFileMenu:
switch( theItem )
{
case kfmExpand:
case kfmOpen:
CustomGetFile(
(FileFilterYDUPP)GetRoutineAddress(MyCustomFileFilter),
-1, *(SFTypeList *)&MyTypeList.typeList,
&mySFR,
CustomGetFileDLOG,
sfgfpos,
(DlgHookYDUPP)GetRoutineAddress(MySFGetDlgHook),
nil,
nil,
nil,
(void *) &MyTypeList
);
if( mySFR.sfGood )
{
/* do something */
BeginOfTask();
gApp.KeysMode = 0;
gApp.KeysOp = 0;
gApp.Op = ( theItem == kfmExpand ? kMisc_gunzip : kMisc_auto );
gApp.Prompt = ( theItem == kfmExpand );
gSufMap.Type = mySFR.sfType;
done = EndOfTask( gzip( &mySFR.sfFile) );
}
break;
case kfmCompress:
StandardGetFile( nil, -1, nil, &mySFR);
if( mySFR.sfGood )
{
/* do something */
BeginOfTask();
gApp.KeysMode = 0;
gApp.KeysOp = 0;
gApp.Op = kMisc_gzip;
gApp.Prompt = TRUE;
gSufMap.Type = mySFR.sfType;
done = EndOfTask( gzip( &mySFR.sfFile) );
}
break;
case kfmQuit:
gApp.quit = TRUE;
done = TRUE;
break;
default:
break;
}
break;
case kEditMenu:
switch( theItem )
{
case kemPrefs:
gApp.PrefsChanged = DoPrefsDialog(&gPrefs, &gApp.DFolder);
if ( ( gPrefs.Compress.IC || gPrefs.Decompress.IC ) && (gSufMap.ICmappings == nil ))
if ( InitICMappings( &(gSufMap.ICinst), &(gSufMap.ICmappings) ) )
{
/* couldn't init it */
gPrefs.Compress.IC = gPrefs.Decompress.IC = FALSE;
DoError(NO_ERR,INFO_ERR,GetErrFmt(GENERIC, CANT_GET_IC));
}
if (( gPrefs.Decompress.Fetch )&&(gSufMap.FPrefs==nil))
if ( InitFetchMappings( &(gSufMap.FPrefsSize), &(gSufMap.FPrefs) ) )
{
/* couldn't init it */
gPrefs.Decompress.Fetch = FALSE;
DoError(NO_ERR,INFO_ERR,GetErrFmt(GENERIC, CANT_GET_FETCH));
}
break;
default:
SystemEdit(theItem-1);
break;
}
break;
default:
break;
}
HiliteMenu(0);
return done;
}
static Boolean DoMouseDown(short windowPart, WindowPtr whichWindow, EventRecord *theEvent)
{
Boolean done=FALSE;
ControlHandle WhichCtl;
switch( windowPart )
{
case inMenuBar:
done = DoCommand( MenuSelect(theEvent->where) );
break;
case inSysWindow:
SystemClick(theEvent, whichWindow);
break;
case inDrag:
if ( whichWindow != FrontWindow() )
{
/* don't do anything, can't drag a back window */
SysBeep(1);
}
else
{
DragWindow(whichWindow, theEvent->where, &qd.screenBits.bounds);
gApp.PrefsChanged = TRUE;
}
break;
case inContent:
GlobalToLocal(&theEvent->where);
if(inButton == FindControl(theEvent->where, whichWindow, &WhichCtl))
{
if(0!=TrackControl(WhichCtl, theEvent->where, nil))
{
SetCursor(&qd.arrow);
done = TRUE;
}
}
break;
case inGrow:
case inGoAway:
/* no such items in MacGzip */
break;
default:
break;
}
return done;
}
/*
* CustomGetFile
*/
static pascal Boolean MyCustomFileFilter(ParmBlkPtr pb, void *myDataPtr)
{
Boolean result ;
register short i;
if (
( ((TypeList *) myDataPtr)->ShowAny ) ||
(((pb->fileParam.ioFlAttrib>>4) & 0x01) == 1) /* is folder */
)
{
result = FALSE;
}
else
{
for(i=0, result = FALSE; i< ((TypeList *) myDataPtr)->numTypes ; i++)
{
if ( result = (
((TypeList *) myDataPtr)->typeList[i] ==
pb->fileParam.ioFlFndrInfo.fdType
))
break;
}
result = !result;
}
return result;
}
static pascal short MySFGetDlgHook( short MySFitem, DialogPtr dlgPtr, void *myDataPtr )
{
short result = MySFitem;
short value;
short iType;
Handle iHandle;
Rect iRect;
switch(MySFitem)
{
case sfHookFirstCall:
GetDItem( dlgPtr, kShowAnyButton,
&iType, &iHandle, &iRect);
if ( ((TypeList *) myDataPtr)->Inited )
SetCtlValue( (ControlHandle) iHandle,
(short) ((TypeList *) myDataPtr)->ShowAny );
else
{
((TypeList *) myDataPtr)->ShowAny =
(Boolean) GetCtlValue( (ControlHandle) iHandle );
((TypeList *) myDataPtr)->Inited = TRUE;
}
break;
case kShowAnyButton:
GetDItem( dlgPtr, kShowAnyButton,
&iType, &iHandle, &iRect);
value = !GetCtlValue( (ControlHandle) iHandle );
SetCtlValue( (ControlHandle) iHandle , value );
((TypeList *) myDataPtr)->ShowAny = (Boolean) value;
result = sfHookRebuildList;
break;
default:
break;
}
return(result);
}
/************************************************************************************
*
* Movable Modal Stuff
*/
void InitMovableModal(long int theEnd, long *now )
{
WindowPtr myWindow;
if (UseMModalProg)
{
/* There is already a window on the screen */
SPDNow=now;
SPDEnd=(theEnd==0?1:theEnd);
greyRect.right = greyRect.left;
InvalRect(&r);
}
else
{
if ( gApp.hasColorQD )
myWindow = GetNewCWindow(kMyModalID, nil, (WindowPtr)-1);
else
myWindow = GetNewWindow(kMyModalID, nil, (WindowPtr)-1);
SetWRefCon(myWindow, (long)DrawMovable);
((WindowPeek)myWindow)->windowKind = kMyModalKind;
/* move it to the saved position */
/* move it to 0,0 to avoid any math at all */
MoveWindow(myWindow, 0, 0, false);
MoveWindow(myWindow, gPrefs.SavedPoint.h, gPrefs.SavedPoint.v, false);
r = myWindow->portRect;
SPDNow=now;
SPDEnd=(theEnd==0?1:theEnd);
UseMModalProg=true;
barRect.left = r.left + BarMargin;
barRect.right = r.right - BarMargin;
barRect.bottom = r.bottom - BarMargin;
barRect.top = barRect.bottom - BarHeight;
ButtonHndl = GetNewControl( kCancelButton, myWindow);
barRect.right -= ( BarMargin + (*ButtonHndl)->contrlRect.right);
OffsetRect(
&((*ButtonHndl)->contrlRect),
barRect.right + BarMargin,
barRect.top -
((*ButtonHndl)->contrlRect.bottom - (*ButtonHndl)->contrlRect.top - BarHeight)/2
);
ShowControl(ButtonHndl);
greyRect.left = barRect.left + 1;
greyRect.right = greyRect.left;
greyRect.bottom = barRect.bottom - 1;
greyRect.top = barRect.top + 1;
ShowWindow(myWindow);
DrawMovable(myWindow);
SetPort(myWindow);
}
}
void SetMMString( const char *fmt, ... )
{
va_list vl;
char StrTmp[256];
va_start(vl,fmt);
vsprintf(StrTmp, fmt, vl);
va_end(vl);
CStrToStr255( SPDPstr, StrTmp );
gDirtyStr = TRUE;
}
static short FixMMString( void )
{
int newWid, newLen, wid;
wid = (r.right - r.left) - 2 * BarMargin;
newWid = StringWidth(SPDPstr);
if (newWid > wid )
{
newLen = (int) SPDPstr[0];
wid = wid - CharWidth('…');
do
{
newWid = newWid - CharWidth(SPDPstr[newLen]);
newLen--;
}while((newWid > wid) && (SPDPstr[0] != 0x00));
newLen ++;
SPDPstr[newLen] = '…';
SPDPstr[0] = (char)newLen;
}
return (StringWidth(SPDPstr));
}
static void DrawMsg(void)
{
FontInfo fInfo;
TextFont( systemFont );
TextSize( 12 );
GetFontInfo( &fInfo );
MsgRect.top = r.top + BarMargin - fInfo.ascent;
MsgRect.left = r.left + BarMargin;
MsgRect.bottom = r.top + BarMargin + fInfo.descent;
// MsgRect.right = MsgRect.left + FixMMString();
FixMMString();
MsgRect.right = r.right - BarMargin;
EraseRect(&MsgRect) ;
MoveTo( BarMargin , BarMargin); /* h, v */
DrawString(SPDPstr);
gDirtyStr = FALSE;
}
void ReleaseMovableModal(void)
{
WindowPtr myWindow = FrontWindow();
if(UseMModalProg)
{
if(ButtonHndl != nil)
DisposeControl(ButtonHndl);
/* the front window really should be my modal window */
/* if it isn't, I'm bailing.*/
gPrefs.SavedPoint.h = myWindow->portRect.left;
gPrefs.SavedPoint.v = myWindow->portRect.top;
LocalToGlobal(&gPrefs.SavedPoint);
if (((WindowPeek)myWindow)->windowKind == kMyModalKind)
CloseWindow(myWindow);
UseMModalProg=false;
}
}
static void DrawMovable(WindowPtr myWindow)
{
WindowPtr tempWP;
BeginUpdate(myWindow);
GetPort(&tempWP);
SetPort(myWindow);
DrawMsg();
DrawBar(kIndicatorOutline | kIndicatorContent);
DrawControls(myWindow);
SetPort(tempWP);
EndUpdate(myWindow);
}
static void DrawBar(short part)
{
RGBColor barColor = {0x4444, 0x4444, 0x4444};
RGBColor emptyBarColor = {0xCCCC, 0xCCCC, 0xFFFF};
RGBColor currentForeColor;
RGBColor currentBackColor;
if ((part & kIndicatorOutline) == kIndicatorOutline)
{
GetBackColor(¤tBackColor) ;
RGBBackColor(&emptyBarColor) ;
EraseRect(&barRect) ;
RGBBackColor(¤tBackColor) ;
FrameRect(&barRect);
greyRect.left = barRect.left + 1;
}
if ((part & kIndicatorContent) == kIndicatorContent)
{
GetForeColor(¤tForeColor);
RGBForeColor(&barColor);
PaintRect(&greyRect);
RGBForeColor(¤tForeColor);
}
}
/************************************************************************************/
HFileInfo gpb;
static int DoOpen( FSSpec *fs )
{
int exitcode = 0;
HFileInfo pb;
pb.ioNamePtr = fs->name;
pb.ioVRefNum = fs->vRefNum;
pb.ioFDirIndex = 0; /* query 1 item */
pb.ioDirID = fs->parID;
PBGetCatInfo( (CInfoPBPtr)&pb, 0 );
if (((pb.ioFlAttrib>>4) & 0x01) == 1)
{
/* Is a Dir */
if ( gPrefs.Folder.RecurseMode == kFold_FNot )
{
exitcode = 3;
}
else
{
gpb.ioNamePtr = fs->name;
gpb.ioVRefNum = fs->vRefNum;
exitcode = RecurseDir(pb.ioDirID);
}
}
else
{
/* Is a File */
gSufMap.Type = pb.ioFlFndrInfo.fdType;
exitcode = gzip( fs );
}
return exitcode;
}
static int RecurseDir(long dirIDToSearch)
{
short int index=1; /* for ioFDirIndex */
FSSpec myFSSpec;
int exitcode = 0;
do
{
gpb.ioDirID = dirIDToSearch;
gpb.ioFDirIndex = index; /* set up the index */
/* we need to do this every time through,
* since GetCatInfo returns ioFlNum
* in this field
*/
err= PBGetCatInfo((CInfoPBPtr)&gpb,false);
if (err == noErr)
{
/* check the file attributes for folderhood */
if (((gpb.ioFlAttrib>>4) & 0x01) == 1)
{
if ( gPrefs.Folder.RecurseMode == kFold_FAll )
{
exitcode = RecurseDir(gpb.ioDirID);
}
else
exitcode = 0;
err = 0;
}
else
{
FSMakeFSSpec(
0,
dirIDToSearch,
gpb.ioNamePtr,
&myFSSpec
);
exitcode =
(0!=new_work( gApp.KeysMode, gApp.Op, gApp.Prompt, &myFSSpec ));
}
index += 1; /* increment the index for GetCatInfo */
}
} while ((err == noErr)&&( exitcode == 0));
if ( err != fnfErr ) exitcode = 1;
return exitcode;
}
/************************************************************************************/
static void BeginOfTask( void )
{
gTask = TRUE;
DisableItem(GetMHandle(kFileMenu), kfmOpen);
DisableItem(GetMHandle(kFileMenu), kfmCompress);
DisableItem(GetMHandle(kFileMenu), kfmExpand);
DisableItem(GetMHandle(kEditMenu), kemPrefs);
}
static Boolean EndOfTask( int errorcode )
{
if ( gApp.Working )
{
if ( empty_work )
{
if ( 0 == errorcode )
{
if ( gPrefs.Misc.BeepWhenDone )
MyBeep(kBeepsnd_ID);
}
ReleaseMovableModal();
gApp.Working = FALSE;
SetCursor(&qd.arrow);
}
if ( SPDNow != nil) *SPDNow = 0;
SPDEnd=INT_MAX;
}
if ( empty_work )
{
gTask = FALSE;
EnableItem(GetMHandle(kFileMenu), kfmOpen);
EnableItem(GetMHandle(kFileMenu), kfmCompress);
EnableItem(GetMHandle(kFileMenu), kfmExpand);
EnableItem(GetMHandle(kEditMenu), kemPrefs);
}
return (( gApp.StartupFiles ) || ( gPrefs.Misc.QuitWhenDone )) && empty_work ;
}